package com.zwr.normal.readwrite;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import static java.lang.Thread.sleep;

/**
 * @author Administrator
 */
public class DataContainer {

    private void a(){
        r.lock();
        try {
            // ...
            w.lock();
            try {
                // ...
            } finally{
                w.unlock();
            }
        } finally{
            r.unlock();
        }
    }


    private Object data;
    private ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock r = rw.readLock();
    private ReentrantReadWriteLock.WriteLock w = rw.writeLock();

    public Object read() {
        System.out.println("获取读锁...");
        r.lock();
        try {
            System.out.println("读取");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return data;
        } finally {
            System.out.println("释放读锁...");
            r.unlock();
        }
    }

    public void write() {
        System.out.println("获取写锁...");
        w.lock();
        try {
            System.out.println("写入");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } finally {
            System.out.println("释放写锁...");
            w.unlock();
        }
    }


    public static void main(String[] args) {
        // Thread-0 锁定期间，Thread-1 的读操作不受影响
        DataContainer dataContainer = new DataContainer();
        new Thread(() -> {
            dataContainer.read();
        }, "t1").start();
        new Thread(() -> {
            dataContainer.read();
        }, "t2").start();

        //测试 读锁-写锁 相互阻塞
        DataContainer dataContainer2 = new DataContainer();
        new Thread(() -> {
            dataContainer2.read();
        }, "t1").start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            dataContainer2.write();
        }, "t2").start();

        //写锁-写锁 也是相互阻塞的，这里就不测试了
    }
}
